<?php
/**
 * +-------------------------------------------------------------
 * |Caption:
 * +-------------------------------------------------------------
 * |Author: Lenny
 * +-------------------------------------------------------------
 * |Email:  1685964109@qq.com
 * +-------------------------------------------------------------
 * |Date:   2024/7/20 上午11:07
 * +-------------------------------------------------------------
 */

namespace app\service;

//use app\admin\model\SysUploadfile;
//use app\store\model\StoreUploadfile;
use OSS\Core\OssException;
use OSS\OssClient;
use think\facade\Env;
use think\file\UploadedFile;
use think\helper\Str;

class UploadService
{
    /**
     * 静态变量，用于存储 UploadService 的实例，以便在程序中多次使用。
     * 类型为 ?UploadService，表示该变量可以存储一个 UploadService 的引用或者 null。
     * 静态变量，表示在整个类中均可访问，不需要实例化类。
     * 初始时，该变量的值为 null。
     */
    public static ?UploadService $_instance = null;

    protected array $options = [];
    private array   $saveData;

    /**
     * 获取 UploadService 实例的方法。
     * 如果 static::$_instance 为 null，则创建一个新的 UploadService 实例并赋值给 static::$_instance。
     * 否则，返回当前的 UploadService 实例。
     */
    public static function instance(): ?UploadService
    {
        if(!static::$_instance) static::$_instance = new static();
        return static::$_instance;
    }

    /**
     * @param array $options
     * @return $this
     */
    public function setConfig(array $options = []): UploadService
    {
        $this->options = $options;
        return $this;
    }

    /**
     * @return array
     */
    public function getConfig(): array
    {
        return $this->options;
    }

    /**
     * @param UploadedFile $file
     * @param string $base_path
     * @return string
     */
    protected function setFilePath(UploadedFile $file, string $base_path = ''): string
    {
        $path = date('Ymd') . '/' . Str::random(3) . time() . Str::random() . '.' . $file->extension();
        return $base_path . $path;
    }

    /**
     * @param UploadedFile $file
     * @return UploadService
     */
    protected function setSaveData(UploadedFile $file): static
    {
        $options        = $this->options;
        $data           = [
                'upload_type'   => $options['upload_type'],
                'original_name' => $file->getOriginalName(),
                'mime_type'     => $file->getMime(),
                'file_size'     => $file->getSize(),
                'file_ext'      => strtolower($file->extension()),
                'create_time'   => time(),
        ];
        $this->saveData = $data;
        return $this;
    }

    /**
     * 本地存储
     */
    public function local(UploadedFile $file, string $type = ''): array
    {
        if ($file->isValid()) {
            $base_path = '/storage/' . date('Ymd') . '/';
            // 上传文件的目标文件夹
            $destinationPath = public_path() . $base_path;
            $this->setSaveData($file);
            // 将文件移动到目标文件夹中
            $move = $file->move($destinationPath, Str::random(3) . time() . Str::random() . session('admin.id') . '.' . $file->extension());
            $url  = $base_path . $move->getFilename();
            $data = ['url' => $url];
            $this->save($url);
            return ['code' => 1, 'data' => $data];
        }
        $data = '上传失败';
        return ['code' => 0, 'data' => $data];
    }

    /**
     * 阿里云OSS
     */
    public function oss(UploadedFile $file,$storeId = 0): array
    {
        $config          = $this->getConfig();;
        $accessKeyId     = $config['engine']['accessKeyId'];
        $accessKeySecret = $config['engine']['accessSecret'];
        $endpoint        = $config['engine']['endpoint'];
        $bucket          = 'dtveek-erp';
        if ($file->isValid()) {
            $object = $this->setFilePath($file, app()->http->getName() . '/');
            try {
                $ossClient       = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
                $_rs             = $ossClient->putObject($bucket, $object, file_get_contents($file->getRealPath()));
                $oss_request_url = $_rs['oss-request-url'] ?? '';
                if (empty($oss_request_url)) return ['code' => 0, 'data' => '上传至OSS失败'];
                $oss_request_url = str_replace('http://', 'https://', $oss_request_url);
                $this->setSaveData($file);
            } catch (OssException $e) {
                return ['code' => 0, 'data' => $e->getMessage()];
            }
            $data = ['url' => $oss_request_url];
//            $this->save($oss_request_url,$storeId);
            return ['code' => 1, 'data' => $data];
        }
        $data = '上传失败';
        return ['code' => 0, 'data' => $data];
    }

    /**
     * 设置保存数据
     */
    protected function save(string $url = '',$storeId = 0): bool
    {
        $data                = $this->saveData;
        $data['url']         = $url;
        $data['upload_time'] = time();
        $appName             = app()->http->getName();
        if($appName === 'admin'){
            return (new SysUploadfile())->save($data);
        }
        if($appName === 'store'){
            $data['store_id'] = $storeId;
            return (new StoreUploadfile())->save($data);
        }
        return true;
    }
}